package com.zenchn.aliyun.oss.api.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.zenchn.aliyun.oss.api.OssCopyService;
import com.zenchn.aliyun.oss.utils.OssCommonUtils;
import com.zenchn.entity.JsonResult;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * com.zenchn.aliyun.oss 拷贝(复制) 实现类
 * @author dingxinfa
 * @date 2018-08-16
 *
 */
@Service
public class OssCopyServiceImpl implements OssCopyService {
	/**
	 * 简单文件拷贝
	 */
	@Override
	public JsonResult<Map> copySimpleFile(String endpoint, String accessKeyId, String accessKeySecret, String sourceBucketName,
                                          String sourceObjectName, String destinationBucketName, String destinationObjectName) {
		JsonResult jsonResult=new JsonResult();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		try {
			// 拷贝文件。
			CopyObjectResult copyObjectResult = ossClient.copyObject(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName);

			if(ossClient.getObjectMetadata(sourceBucketName, sourceObjectName).getETag().equals(copyObjectResult.getETag())){
				jsonResult.setSuccess(true);
				jsonResult.setCode(1);

				ObjectMetadata objectMeta = ossClient.getObjectMetadata(destinationBucketName, destinationObjectName);
				Map<String, Object> data = new HashMap<>();
				data.put("contentType", objectMeta.getContentType());
				data.put("contentLength", objectMeta.getContentLength());
				data.put("lastModified", objectMeta.getLastModified());
				jsonResult.setData(data);

			}
			// 关闭OSSClient。
			ossClient.shutdown();
		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		}finally{
			if (ossClient != null) {
            	ossClient.shutdown();
            }
		}
		return jsonResult;
	}

	
	/**
	 * 拷贝文件
	 */
	@Override
	public JsonResult<Map> copyLargeFile(
			String endpoint,String accessKeyId,String accessKeySecret,String sourceBucketName,String sourceObjectName,
			String destinationBucketName, String destinationObjectName,String callbackUrl) {

		JsonResult jsonResult=new JsonResult();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		try {
			ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName);
			// 获取被拷贝文件的大小。
			long contentLength = objectMetadata.getContentLength();
			// 设置分片大小为10MB。
			long partSize = 1024 * 1024 * 10;
			// 计算分片总数。
			int partCount = (int) (contentLength / partSize);
			if (contentLength % partSize != 0) {
				partCount++;
			}
			System.out.println("total part count:" + partCount);
			// 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。
			InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationObjectName);
			InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
			String uploadId = initiateMultipartUploadResult.getUploadId();
			// 分片拷贝。
			List<PartETag> partETags = new ArrayList<PartETag>();
			for (int i = 0; i < partCount; i++) {
				// 计算每个分片的大小。
				long skipBytes = partSize * i;
				long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
				// 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。
				UploadPartCopyRequest uploadPartCopyRequest =
						new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName);
				uploadPartCopyRequest.setUploadId(uploadId);
				uploadPartCopyRequest.setPartSize(size);
				uploadPartCopyRequest.setBeginIndex(skipBytes);
				uploadPartCopyRequest.setPartNumber(i + 1);
				UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
				// 将返回的分片ETag保存到partETags中。
				partETags.add(uploadPartCopyResult.getPartETag());
			}
			// 提交分片拷贝任务。
			CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
					destinationBucketName, destinationObjectName, uploadId, partETags);

			if (null != callbackUrl){
				// 设置上传成功回调，参数为Callback类型。
				completeMultipartUploadRequest.setCallback(OssCommonUtils.buildCallback(callbackUrl,destinationObjectName));
			}

			ossClient.completeMultipartUpload(completeMultipartUploadRequest);

			ObjectMetadata objectMeta = ossClient.getObjectMetadata(destinationBucketName, destinationObjectName);
			Map<String, Object> data = new HashMap<>();
			data.put("contentType", objectMeta.getContentType());
			data.put("contentLength", objectMeta.getContentLength());
			data.put("lastModified", objectMeta.getLastModified());
			jsonResult.setData(data);

			jsonResult.setSuccess(true);
			jsonResult.setCode(1);
			// 关闭OSSClient。
			ossClient.shutdown();
		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		}finally{
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}
		return jsonResult;
	}
}
